<?php
/**
 * @author gabriel
 *
 */
class Site_Model_Site extends Promotor_Model_Scaffold {
	
	protected $_dbTableClass = 'Site_Model_DbTable_Site';

	protected $_cachedMethods = array(
		'findByAlias',
		'findById',
		'findAttachments',
		'findAll',
		'findByIdentificationAndLocale',
		'findOne',
		'getTemplateData',
		'findChildrens',
		'findParents'
	);
	
	/**
	 * @return Zend_Db_Table_Select
	 */
	public function selectList() {
		return $this->getDbTable();
	}
	
	/**
	 * @param Zend_Db_Table_Row_Abstract|string $row
	 * @return array
	 */
	public function getTemplateData(Zend_Db_Table_Row_Abstract $row) {
		try {
			$row = $row->findParentRow('System_Model_DbTable_Template');
		} catch (Zend_Db_Exception $e) {
			$this->_addException($e);
			$this->_setStatus(self::FAILURE);
			return array();
		}

		if (null === $row) {
			return array();
		}

		$this->_setStatus(self::SUCCESS);
		return $row->toArray();
	}

	/**
	 * @return Zend_Db_Select
	 */
	public function selectAttached($id, $type = null) {
		$id = (int) $id;

		$table = $this->getDbTable();
		$adapter = $table->getAdapter();

		// news
		$select1 = new Zend_Db_Select($adapter);
		$select1->from(
					array('shs' => 'site_has_news'),
					array(
						'type' => new Zend_Db_Expr("'news'"),
						'custom_one' => new Zend_Db_Expr("NULL"),
						'custom_two' => new Zend_Db_Expr("NULL"),
						'site_id',
						'item_id' => 'shs.news_id'))
				->joinInner(
					array('n' => 'news'),
					'n.id = shs.news_id', 
					array('id', 'name', 'time_create', 'description'))
				->where('site_id = ?', $id)
				->where('n.publicated = ?', '1');

		// albums
		/*$select2 = new Zend_Db_Select($adapter);
		$select2->from(
					array('shga' => 'site_has_gallery_album'),
					array(new Zend_Db_Expr("'album'"), 'site_id'))
				->joinInner(
					array('ga' => 'gallery_album'),
					'ga.id = shga.album_id', 
					array('id', 'name', 'time_create', 'description', 'publicated'))
				->where('site_id = ?', $id)
				->where('publicated = ?', '1');*/
				
		// album images
		$select2 = new Zend_Db_Select($adapter);
		$select2->from(
					array('gi' => 'gallery_image'),
					array(
						new Zend_Db_Expr("'album'"),
						new Zend_Db_Expr('gi.image'),
						new Zend_Db_Expr("'news'"),
						))
				->joinInner(
					array('ga' => 'gallery_album'),
					'ga.id = gi.album_id',
					array(
						new Zend_Db_Expr('shga.site_id'),
						new Zend_Db_Expr('gi.id'),
						'id',
						'name',
						'time_create',
						'description'))
				->joinInner(
					array('shga' => 'site_has_gallery_album'),
					'ga.id = shga.album_id',
					array())
				
				->where('site_id = ?', $id)
				->where('gi.publicated = ?', '1')
				->where('ga.publicated = ?', '1');
				
		// album media
		$select3 = new Zend_Db_Select($adapter);
		$select3->from(
					array('gm' => 'gallery_media'),
					array(
						new Zend_Db_Expr("'album_media'"),
						new Zend_Db_Expr('gm.image'),
						new Zend_Db_Expr('gm.media'),
						))
				->joinInner(
					array('ga' => 'gallery_album'),
					'ga.id = gm.album_id',
					array(
						new Zend_Db_Expr('shga.site_id'),
						new Zend_Db_Expr('gm.id'),
						'id',
						'name',
						'time_create',
						'description'))
				->joinInner(
					array('shga' => 'site_has_gallery_album'),
					'ga.id = shga.album_id',
					array())
				
				->where('site_id = ?', $id)
				->where('gm.publicated = ?', '1')
				->where('ga.publicated = ?', '1');

		switch($type) {
			case 'news':  $select = $select1; break;
			case 'image': $select = $select2; break;
			case 'media': $select = $select3; break;

			default:
				$union = array($select1, $select2, $select3);
				$select = new Zend_Db_Select($adapter);
				$select->union($union);
		}

		return $select;
	}
	
	/**
	 * @param Zend_Db_Table_Row_Abstract|string $row
	 * @param string $type
	 * @param integer $rowCount
	 * @param integer $page
	 * @return array
	 */
	public function findAttachments($row, $type =  null, $rowCount = null, $page = null) {
		if (is_int($row)) {
			$row = $this->findById($row, false);
		} else
		if (is_string($row)) {
			$row = $this->findByAlias($row, false);
		}

		if (!$row instanceof Zend_Db_Table_Row_Abstract) {
			$this->_setStatus(self::FAILURE);
			return;
		}
		
		$select = $this->selectAttached($row->id, $type);
		$select
			->reset(Zend_Db_Select::ORDER) // bo KontorX_Db_Tree_*... dodaje automatycznie order by!
			->order('time_create DESC');

		if (is_integer($rowCount)) {
			$select->limitPage((int) $page, $rowCount);
		}

		try {
			$stmt = $select->query();
			$this->_setStatus(self::SUCCESS);
		} catch(Zend_Db_Exception $e) {
			$this->_setStatus(self::FAILURE);
			$this->_addException($e);
			return;
		}

		$attachment = array();
		$storage = array();
		while ($data = $stmt->fetch()) {
			$key = $data['type'] . $data['id'];
			switch ($data['type']) {
				default:
				case 'news':
					$attachment[$key] = $data; break;

				case 'album':
					if (!isset($attachment[$key])) {
						$attachment[$key] = $data;
						$attachment[$key]['album'] = array();
					}

					$data = $attachment[$key]['album'][] = array(
						'id' 	=> $data['item_id'],
						'image' => $data['custom_one']
					);
					break;

				case 'album_media':
					$key = 'album' . $data['id'];
					if (!isset($attachment[$key])) {
						$attachment[$key] = $data;
						$attachment[$key]['album'] = array();
					}
					$data = $attachment[$key]['album'][] = array(
						'id' 	=> $data['item_id'],
						'image' => $data['custom_one'],
						'media' => $data['custom_two']
					);
					break;
			}
			
			if (!isset($storage[$type])) {
				$storage[$type] = array();
			}
			$storage[$type][] = $data;
		}
		
		if (null !== $type && isset($storage[$type])) {
			return $storage[$type];
		}
		
		return $attachment;
	}
	
	/**
	 * @param string|integer|KontorX_Db_Table_Tree_Row_Abstract $row
	 * @return KontorX_Db_Table_Tree_Rowset_Abstract
	 */
	public function findChildrens($row, $depthLevel = null) {
		$attachment = array();

		if (is_int($row)) {
			$row = $this->findById($row, false);
		} else
		if (is_string($row)) {
			$row = $this->findByAlias($row, false);
		}

		if (!$row instanceof KontorX_Db_Table_Tree_Row_Abstract) {
			$this->_setStatus(self::FAILURE);
			return;
		}
		
		$table = $this->getDbTable();
		$select = $table->select()
			->where('publicated = ?', '1');
		
		/* @var $row KontorX_Db_Table_Tree_Row_Abstract */
		$rowset = $row->findChildrens($depthLevel, $select);
		return $rowset;
	}
	
	/**
	 * @param string|integer|KontorX_Db_Table_Tree_Row_Abstract $row
	 * @return KontorX_Db_Table_Tree_Rowset_Abstract
	 */
	public function findParents($row, $depthLevel = null) {
		$attachment = array();

		if (is_int($row)) {
			$row = $this->findById($row, false);
		} else
		if (is_string($row)) {
			$row = $this->findByAlias($row, false);
		}

		if (!$row instanceof KontorX_Db_Table_Tree_Row_Abstract) {
			$this->_setStatus(self::FAILURE);
			return;
		}
		
		$table = $this->getDbTable();
		$select = $table->select()
			->where('publicated = ?', '1');
		
		/* @var $row KontorX_Db_Table_Tree_Row_Abstract */
		$rowset = $row->findParents($depthLevel, $select);
		return $rowset;
	}

	/**
	 * @param string $locale
	 * @return Zend_Navigation
	 */
	public function getNavigation($locale = null) {
		$rowset = $this->findAllCache(null, false, $locale);
		// ratuje przed fatal error
		$rowset->setTable($this->getDbTable());

		$navigation = new KontorX_Navigation_Recursive($rowset);
		$navigation->accept(new Promotor_Navigation_Recursive_Visitor_Site());

		return $navigation->create();
	}
	
	/**
	 * @param integer $pkNode
	 * @param integer $pkParent
	 * @return void
	 */
	public function move($pkNode, $pkParent = null, $locale = null)
	{
        $row = $this->findByIdentificationAndLocale($pkNode, $locale, false, false);
       
        if (!$row instanceof KontorX_Db_Table_Tree_Row_Interface)
        {
            $this->_setStatus(self::FAILURE);
			$this->_addMessage('Record do not exsists or is not instance of "KontorX_Db_Table_Tree_Row_Interface"');
            return;
        }

        $row->setRoot(true);
        if (is_numeric($pkParent))
        {
        	$parentRow = $this->findByIdentificationAndLocale($pkParent, $locale, false, false);
        	if ($parentRow instanceof KontorX_Db_Table_Tree_Row_Interface)
        	{
        		$row->setParentRow($parentRow);
        		$row->setRoot(false);
        	} else {
        		$this->_addMessage(sprintf('Parent row is null for id "%d"', $pkParent));
        	}
        }

        try {
            $row->save();
            $this->_setStatus(self::SUCCESS);
        } catch (Zend_Db_Table_Exception $e) {
			$this->_addException($e);
			$this->_setStatus(self::FAILURE);
        }
	}

	/**
	 * @param Zend_File_Transfer_Adapter_Http $transfer
	 * @return void
	 */
	public function addFromOdt(Zend_File_Transfer_Adapter_Http $transfer) {
		if (!$transfer->isUploaded('file')) {
			$this->_setStatus(self::FAILURE);
			$this->_addMessage('file is not uploaded');
			return;
		}

		$info = $transfer->getFileInfo('file');
		$path = $info['file']['tmp_name'];
		$name = $info['file']['name'];

		$f = new KontorX_Filter_Word_Rewrite();
		$name = $f->filter($name);
		
		$imagepath = "upload/site/odt/$name";
		
		$odf = new KontorX_Odf_Import($path);
		$odf->setType(KontorX_Odf_Import::TYPE_ODT);
		$odf->setImagePath($imagepath);

		$pictures = $odf->getFilesContent(KontorX_Odf_Import::PICTURE);
		if (count($pictures)) {
			$file = new KontorX_File_Write();
			$file->setBasedir(PUBLIC_PATHNAME);
			$file->setForce(true);
			$file->setChmod(0777, KontorX_File_Write::CHMOD_DIR);
			$file->setChmod(0666, KontorX_File_Write::CHMOD_FILE);
			
			foreach ($pictures as $info) {
				list($path, $content) = $info;

				try {
					$file->write("$imagepath/$path", $content);
				} catch (KontorX_File_Exception $e) {
					$this->_setStatus(self::FAILURE);
					$this->_addMessage($e->getMessage());
				}
			}
		}

		$table = $this->getDbTable();
		$row = $table->createRow(array(
			'name' => $name,
			'content' => $odf->import()
		));

		try {
			$result = $row->save();
			$this->_setStatus(self::SUCCESS);
			return $result;
		} catch (Zend_Db_Table_Exception $e) {
			$this->_setStatus(self::FAILURE);
			$this->_addMessage($e->getMessage());
		}		
	}
	
	/**
	 * @param integer $id
	 * @param bool $asArray
	 * @return array|KontorX_Db_Table_Tree_Row_Abstract
	 */
	public function findById($id, $asArray = true) {
	$table = $this->getDbTable();
		$where = $table->getAdapter()->quoteInto('id = ? AND publicated IN(\'1\',\'2\')', $id, Zend_Db::INT_TYPE);

		try {
			$row = $table->fetchRow($where);
			if(!$row instanceof Zend_Db_Table_Row_Abstract) {
				$this->_setStatus(self::FAILURE);
				return;
			}
			$this->_setStatus(self::SUCCESS);
			return $asArray
				? $row->toArray()
				: $row;
		} catch (Zend_Db_Table_Exception $e) {
			$this->_setStatus(self::FAILURE);
			$this->_addMessage($e->getMessage());
		}
	}
	
	/**
	 * @param string $alias
	 * @param bool $asArray
	 * @return array|KontorX_Db_Table_Tree_Row_Abstract
	 */
	public function findByAlias($alias, $asArray = true) {
		$table = $this->getDbTable();
		$where = $table->getAdapter()->quoteInto('alias = ? AND publicated IN(\'1\',\'2\')', $alias);

		try {
			$row = $table->fetchRow($where);
			if(!$row instanceof Zend_Db_Table_Row_Abstract) {
				$this->_setStatus(self::FAILURE);
				return;
			}
			$this->_setStatus(self::SUCCESS);
			return $asArray
				? $row->toArray()
				: $row;
		} catch (Zend_Db_Table_Exception $e) {
			$this->_setStatus(self::FAILURE);
			$this->_addException($e);
		}
	}
	
	/**
	 * @return array|KontorX_Db_Table_Tree_Row_Abstract
	 */
	public function findByIdentificationAndLocale($identyfication, $locale = null, $asArray = true, $publicated = true) {
		$table = $this->getDbTable();
		$db = $table->getAdapter();

		if (is_numeric($identyfication)) {
			$where = $db->quoteInto('id = ?', $identyfication);
		} else {
			$identyfication = $db->quoteInto('alias = ?', $identyfication);
			$where = $identyfication;
		}

		if (strlen($locale) > 0)
		{
			$locale = $db->quoteInto('locale = ?', strtolower($locale));
			$where .= ' AND ' . $locale;
		}

		if (true === $publicated)
		{
			$where .= ' AND publicated IN(\'1\',\'2\')';
		}
		
		$this->_addMessage($where);
		
		try {
			$row = $table->fetchRow($where);
			if(!$row instanceof Zend_Db_Table_Row_Abstract) {
				$this->_setStatus(self::FAILURE);
				return;
			}
			$this->_setStatus(self::SUCCESS);
			return $asArray
				? $row->toArray()
				: $row;
		} catch (Zend_Db_Table_Exception $e) {
			$this->_setStatus(self::FAILURE);
			$this->_addException($e);
		}
	}

	/**
	 * @param int|string $identification
	 * @param bool $asArray
	 * @return array|KontorX_Db_Table_Tree_Row_Abstract|null
	 */
	public function findOne($identification, $asArray = true) {
		if (is_numeric($identification)) {
			return $this->findById($identification, $asArray);
		} else
		if (is_string($identification)) {
			return $this->findByAlias($identification, $asArray);
		}

		return null;
	}

	/**
	 * @param Zend_Db_Select $select
	 * @param array $asArray
	 * @param string $locale
	 * @return void
	 */
	public function findAll(Zend_Db_Select $select = null, $asArray = true, $locale = null) {

		$table = $this->getDbTable();
		if (null === $select) {
			$select = $table->select();
		}

		$select
			->where('publicated = ?', '1')
			->order('idx ASC');

		if (strlen($locale) > 1)
		{
			$select->where('locale = ?', strtolower($locale));
		}
			
		try {
			$rowset = $table->fetchAll($select);
			
			$this->_setStatus(self::SUCCESS);
			
			return $asArray
				? $rowset->toArray() 
				: $rowset;

		} catch(Zend_Db_Exception $e) {
			$this->_setStatus(self::FAILURE);
			$this->_addException($e);
		}
	}
	
	/**
	 * @return void
	 */
	public function export() {
		$table = $this->getDbTable();
		
		try {
			$rowset = $table->fetchAll();
		} catch (Zend_Db_Exception $e) {
			$this->_setStatus(self::FAILURE);
			$this->_addException($e);
			return;
		}
		
		$path = TMP_PATHNAME . DIRECTORY_SEPARATOR . 'site_export.csv';
        $writer = new Csv_Writer($path);
		
		$recursive = new RecursiveIteratorIterator($rowset, RecursiveIteratorIterator::SELF_FIRST);
		while ($recursive->valid()) {
			$current = $recursive->current();
			$writer->writeRow($current->toArray());
			$recursive->next();
		}

		try {
	       	$writer->close();
	       	$this->_setStatus(self::SUCCESS);
        } catch (Csv_Exception_CannotAccessFile $e) {
        	$this->_setStatus(self::FAILURE);
        	$this->_addException($e);
        }
        
        return $path;
	}
	
	public function prepareCheckedData(array $data) {
		$result = array();
		foreach($data as $val)
		{
			$result[] = $val['id'];
		}
		return $result;
	}
	
	/**
	 * @param stribng $locale
	 * @param array $sitesPK
	 */
	public function copy($locale, array $sitesPK) {
		$table = $this->getDbTable();

//		$newRows = array();
//		$idsReplace = array(
//			array(),
//			array()
//		);
		
		$rowset = $table->find($sitesPK);
		foreach($rowset as $row)
		{
			if ($row->locale == $locale)
			{
				continue;
			}
			/* @var $row KontorX_Db_Table_Tree_Row */
			$newRow = clone $row;
			$newRow->locale = $locale;

			try {
				$newRow->save();
				
//				if ($newRow->depth > 1)
//				{
//					$newRows[] = $newRow;
//					$idsReplace[0][] = $row->id . '/';
//					$idsReplace[1][] = $newRow->id . '/';
//				}

				$this->_setStatus(self::SUCCESS);
			} catch (Zend_Db_Table_Exception $e) {
				$this->_addException($e);
				$this->_setStatus(self::FAILURE);
	        }
		}
		
//		/**
//		 * Poprawianie zagniezdzeń 
//		 */
//		foreach($newRows as $row)
//		{
//			$row->level = str_replace($idsReplace[0], $idsReplace[1], $row->level);
//			try {
//				$newRow->save();
//				$this->_setStatus(self::SUCCESS);
//			} catch (Zend_Db_Table_Exception $e) {
//				$this->_addException($e);
//				$this->_setStatus(self::FAILURE);
//	        }
//		}
	}
}